package com.ybkj.o2o.zhuanxian.manager.impl;

import java.text.CollationKey;
import java.text.Collator;
import java.util.*;

import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.util.CollectionUtils;

import com.ybkj.o2o.zhuanxian.common.DataGrid;
import com.ybkj.o2o.zhuanxian.common.config.DaijiaApi;
import com.ybkj.o2o.zhuanxian.entity.Car;
import com.ybkj.o2o.zhuanxian.entity.CarAndLine;
import com.ybkj.o2o.zhuanxian.entity.Line;
import com.ybkj.o2o.zhuanxian.manager.LineManager;
import com.ybkj.o2o.zhuanxian.service.CarAndLineService;
import com.ybkj.o2o.zhuanxian.service.CarService;
import com.ybkj.o2o.zhuanxian.service.LineService;

@Service
public class DefaultLineManager implements LineManager {

  @Autowired
  private LineService lineService;
  @Autowired
  private CarService carService;
  @Autowired
  private CarAndLineService carAndLineService;
  @Autowired
  private DaijiaApi daijiaApi;

  @Override
  @Transactional(rollbackFor = Exception.class)
  public Line create(Line line) {
    line = lineService.create(line);
    return line;
  }

  @Override
  public Line findById(Long id, String appKey) {
    return lineService.findById(id, appKey);
  }

  @Override
  @Transactional(rollbackFor = Exception.class)
  public void deleteLine(Long id, String appKey) {
    carAndLineService.deleteByLine(id);
    lineService.deleteLine(id, appKey);
  }

  @Override
  public DataGrid<Line> findByParam(Long companyId, String companyName,
      String name,String startCity, String startAddress, String endCity,
      String endAddress, Integer page, Integer rows, String appKey) {
    Integer limit = null;
    if (page != null && rows != null) {
      limit = (page - 1) * rows;
    }
    List<Line> list =
        lineService.findByParam(companyId, companyName, name, startCity, startAddress, endCity,
            endAddress, limit, rows, appKey);
    Long count =
        lineService.countByParam(companyId, companyName, name, startCity, startAddress, endCity,
            endAddress, appKey);
    DataGrid<Line> data = new DataGrid<Line>();
    data.setRows(list);
    data.setTotal(count);
    return data;
  }
  
  @Override
  public DataGrid<Map<String, Object>> findLineByParams(
      String keyWord, Integer page, Integer rows, String serverUrl, String appKey, Integer isWX) {
    Integer limit = null;
    if (page != null && rows != null) {
      limit = (page - 1) * rows;
    }
    List<Line> list = lineService.findLineByParams(keyWord, limit, rows, appKey);
    /** ---隐藏所有逆向线路 -----*/
    //判断是否是微信请求，如果是(isWX==1)，不隐藏线路
    if(isWX == null || isWX != 1){
      //用于存放需要隐藏的线路id
      List<Long> lineIdList = new ArrayList<>();
      //用于存放需要隐藏的线路
      List<Line> lineList = new ArrayList<>();
      for(Line line : list){
        String startAddress = line.getStartAddress();
        String endAddress = line.getEndAddress();
        boolean exist = false;
        for(Long id : lineIdList){
          if(line.getId() == id)
            exist = true;
        }
        if(exist) continue;
        for(Line l : list){
          if(l.getStartAddress().equals(endAddress) && l.getEndAddress().equals(startAddress)){
            lineList.add(l);
            lineIdList.add(l.getId());
          }
        }
      }
      for(Line line : lineList){
        list.remove(line);
      }
    }
    /**------------------*/
    List<Map<String, Object>> lineMap = new ArrayList<Map<String, Object>>();
    if (!CollectionUtils.isEmpty(list)) {
      for (Line line : list) {
        Map<String, Object> map = new HashMap<String, Object>();
        map.put("contactNumber",line.getContactNumber());
        map.put("lineId", line.getId());
        map.put("companyId", line.getCompanyId());
        map.put("companyName", line.getCompanyName());
         
        Map<String, Object> lineMoney = daijiaApi.findArea(serverUrl, line.getId());
         
        map.put("jihuoMoney", lineMoney.get("jihuoMoney"));
        map.put("baocheMoney", lineMoney.get("baocheMoney"));
        map.put("pincheMoney", lineMoney.get("pincheMoney"));
        
        map.put("pincheAreaId", line.getAreaId());
        map.put("baocheAreaId", line.getBaocheAreaId());
        map.put("jihuoAreaId", line.getJihuoAreaId());
        
        map.put("name", line.getName());
        map.put("startCity", StringUtils.isNotBlank(
            line.getStartCity()) ? line.getStartCity().split("-")[1] : "");
        map.put("startAddress", line.getStartAddress());
        map.put("endCity",StringUtils.isNotBlank(
            line.getEndCity()) ? line.getEndCity().split("-")[1] : "");
        map.put("endAddress", line.getEndAddress());
        map.put("appKey", line.getAppKey());
        map.put("contactNumber", line.getContactNumber());

        List<Car> cars = carService.findByParam(line.getId(), line.getName(), line.getCompanyId(), line.getCompanyName(), null, null,
                new Integer[]{Car.CAR_FREE}, null, null, limit, rows, appKey);
        map.put("numberOfVehicles",cars.size());
        if(null!=cars) {
          List<Integer> peopleNumbers = new ArrayList<>();
          for (Car car : cars) {
            if(null!=car.getRidepeopleNumber()) {
              peopleNumbers.add(car.getRidepeopleNumber());
            }
          }
          if(cars.size()>1) {
            Collections.sort(peopleNumbers, new Comparator<Integer>() {
              public int compare(Integer o1, Integer o2) {
                return o2 - o1;
              }
            });
          }
          if(!peopleNumbers.isEmpty()) {
            map.put("peopleNumber", peopleNumbers.get(0));
          }
        }

        lineMap.add(map);
      }
    }
    
    Long count = lineService.countLineByParams(keyWord, appKey);
    DataGrid<Map<String, Object>> data = new DataGrid<Map<String, Object>>();
    data.setRows(lineMap);
    data.setTotal(count);
    return data;
  }
  
  @Override
  public DataGrid<Map<String, Object>> findEndInfoByStartInfo(
		  String startCity, String startAddress, Integer page, Integer rows,String serverUrl, String appKey) {
	  Integer limit = null;
	    if (page != null && rows != null) {
	      limit = (page - 1) * rows;
	    }
	    List<Line> list = lineService.findEndByStart(startCity, startAddress, limit, rows, appKey);  
	    List<Map<String, Object>> lineMap = new ArrayList<Map<String, Object>>();
	    if (!CollectionUtils.isEmpty(list)) {
	      for (Line line : list) {
	        Map<String, Object> map = new HashMap<String, Object>();
	        map.put("lineId", line.getId());
	        map.put("companyId", line.getCompanyId());
	        map.put("companyName", line.getCompanyName());
	         
	        Map<String, Object> lineMoney = daijiaApi.findArea(serverUrl, line.getId());
	         
	        map.put("jihuoMoney", lineMoney.get("jihuoMoney"));
	        map.put("baocheMoney", lineMoney.get("baocheMoney"));
	        map.put("pincheMoney", lineMoney.get("pincheMoney"));
	        
	        map.put("pincheAreaId", line.getAreaId());
	        map.put("baocheAreaId", line.getBaocheAreaId());
	        map.put("jihuoAreaId", line.getJihuoAreaId());
	        
	        map.put("name", line.getName());
	        map.put("startCity", StringUtils.isNotBlank(
	            line.getStartCity()) ? line.getStartCity().split("-")[1] : "");
	        map.put("startAddress", line.getStartAddress());
	        map.put("endCity",StringUtils.isNotBlank(
	            line.getEndCity()) ? line.getEndCity().split("-")[1] : "");
	        map.put("endAddress", line.getEndAddress());
	        map.put("appKey", line.getAppKey());
	        lineMap.add(map);
	      }
	    }
	    
	    Long count = lineService.countLineByStart(startCity, startAddress, appKey);
	    DataGrid<Map<String, Object>> data = new DataGrid<Map<String, Object>>();
	    data.setRows(lineMap);
	    data.setTotal(count);
	    return data;
  }

  @Override
  public void update(Line line) {
    line.setUpdated(new Date());
    carAndLineService.updateLineNameByLine(line.getId(), line.getName());
    lineService.update(line);
  }

  @Override
  public List<Line> findByCar(Long carId, String appKey) {
    List<CarAndLine> carAndLines = carAndLineService.findByCar(carId);
    List<Line> lines = new ArrayList<Line>();

    if (!CollectionUtils.isEmpty(carAndLines)) {
      List<Long> ids = new ArrayList<Long>();
      for (CarAndLine carAndLine : carAndLines) {
        ids.add(carAndLine.getLineId());
      }
      lines = lineService.findByIds(ids);
    }

    return lines;
  }

  @Override
  public List<Car> findCarByLine(Long lineId, String appKey) {
    List<CarAndLine> cals = carAndLineService.findByLine(lineId);
    List<Long> ids = new ArrayList<Long>();
    List<Car> cars = new ArrayList<Car>();

    if (!CollectionUtils.isEmpty(cals)) {
      for (CarAndLine carAndLine : cals) {
        ids.add(carAndLine.getCarId());
      }
      cars = carService.findByIds(ids);
    }

    return cars;

  }

  @Override
  public List<Line> queryLineAll(String city, String appKey) {
    List<Line> list = lineService.findAll(city, appKey);
    List<Line> tempAll = lineService.findAll(null, appKey);
    List<Line> addList = new LinkedList<Line>();
    for (Line line : tempAll) {
      boolean flag = true;
      for (Line line2 : list) {
        if (line.getId().equals(line2.getId())) {
          flag = false;
          break;
        }
      }
      if (flag) {
        addList.add(line);
      }
    }
    Collections.sort(addList, new LineComparator());
    list.addAll(addList);
    return list;
  }

  @Override
  public List<Line> findLineByCompany(Long companyId, String city, String appKey) {

    List<Line> list = lineService.findLineByCompany(companyId, city, appKey);
    List<Line> tempAll = lineService.findAll(null, appKey);
    List<Line> addList = new LinkedList<Line>();
    for (Line line : tempAll) {
      boolean flag = true;
      for (Line line2 : list) {
        if (line.getId().equals(line2.getId())) {
          flag = false;
          break;
        }
      }
      if (flag) {
        addList.add(line);
      }
    }
    Collections.sort(addList, new LineComparator());
    list.addAll(addList);
    return list;
  }

  @Override
  public List<Line> findLineByEmploy(Long employId, String appKey) {
    Car car = carService.findByEmploy(employId, appKey);
    List<Line> list = new ArrayList<Line>();
    if (car != null) {
      list = this.findByCar(car.getId(), appKey);

    }
    return list;
  }

  @Override
  public boolean isAlikeLine(Long companyId, String startCity, String startAddress, String endCity,
      String endAddress) {
    List<Line> lines =
        lineService.findByCityAndAddress(companyId, startCity, startAddress, endCity, endAddress);
    return CollectionUtils.isEmpty(lines) ? false : true;
  }

  @Override
  public List<Line> findStartEndByLine(String startCity, String endCity, String appKey) {
    return lineService.findStartEndByLine(startCity, endCity, appKey);
  }

  @Override
  public boolean isUpdateAlikeLine(Long id, Long companyId, String startCity, String startAddress,
      String endCity, String endAddress) {
    List<Line> lines =
        lineService.findByCityAndAddress(companyId, startCity, startAddress, endCity, endAddress);
    if (!CollectionUtils.isEmpty(lines)) {
      boolean flag = false;
      for (Line line : lines) {
        if (!line.getId().equals(id)) {
          flag = true;
          break;
        }
      }
      if (flag) {
        return true;
      } else {
        return false;
      }
    } else {
      return true;
    }

  }

  @Override
  public List<Line> queryline(String city, String startAddress, String endCity,
      boolean isStatus, String appKey) {
    List<Line> lines = null;
    if (isStatus) {
      lines = lineService.queryLineByStartCity(
          StringUtils.isNotBlank(city) ? "%" + city + "%" : null,appKey);
    } else {
      lines = lineService.queryEndLineBySatrt(StringUtils.isNotBlank(city) ? "%" + city
              + "%" : null,
              StringUtils.isNotBlank(startAddress) ? "%" + startAddress + "%" : null,
              StringUtils.isNotBlank(endCity) ? "%" + endCity + "%" : null,appKey);
    }
    return lines;
  }

  @Override
  public boolean isIpentity(Long companyId, String startCity, String startAddress, String endCity,
      String endAddress, String appKey) {

    return lineService.countByAddress(companyId,startCity,
        startAddress,endCity,endAddress,appKey) <= 0 ? false : true;
  }

  @Override
  public boolean isUpdateIpentity(Long id, Long companyId, String startCity, String startAddress,
      String endCity, String endAddress, String appKey) {
    List<Line> lines = lineService.findByAddress(companyId,startCity,startAddress,
        endCity,endAddress,appKey);
    if (CollectionUtils.isEmpty(lines)) {
      return false;
    }
    boolean exits = false;
    for (Line line : lines) {
      if (!line.getId().equals(id)) {
        exits = true;
        break;
      }
    }
    return exits;
  }

  @Override
  public List<String> querylineByCity(String city, String appKey) {
    List<Line> lines = lineService.querylineByCity(city,appKey);
    List<String> address = new LinkedList<>();
    for (Line line : lines) {
      if (line.getStartCity().contains(city)) {
        address.add(line.getStartAddress());
      }
      if (line.getEndCity().contains(city)) {
        address.add(line.getEndAddress());
      }
    }

    return address;
  }

  @Override
  public List<Line> lineIsExist(String startCity, String startAddress, String endcity,
      String endAddress, String appKey) {

    return lineService.lineIsExist(startCity,startAddress,endcity,endAddress,appKey);
  }

  @Override
  public List<Line> findLineByName(String name, String appKey, Long companyId) {
    return lineService.findLineByName(name,appKey,companyId);
  }

  class LineComparator implements Comparator<Line> {

    private Collator collator = Collator.getInstance();

    public LineComparator() {}

    public int compare(Line o1, Line o2) {
      // 把字符串转换为一系列比特，它们可以以比特形式与 CollationKeys 相比较
      CollationKey key1 = collator.getCollationKey(o1.getName());
      // 要想不区分大小写进行比较用o1.toString().toLowerCase()
      CollationKey key2 = collator.getCollationKey(o2.getName());
      return key1.compareTo(key2);
      // 返回的分别为1,0,-1 分别代表大于，等于，小于。要想按照字母降序排序的话 加个“-”号
    }
  }
}


